﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Navigation;
using Microsoft.Phone.Controls;
using Microsoft.Phone.Shell;
using TheVerge.Base;
using TheVerge.Base.Platform;
using TheVerge.Base.Models;
using System.Windows.Data;
using System.Windows.Media;
using Coding4Fun.Toolkit.Controls;
using System.Windows.Input;

namespace TheVerge.Phone.Controls
{
    public partial class CommentsControl : UserControl
    {
        private VMComments _ViewModel;

        public bool IsAddCommentDialogVisible { get; private set; }

        public CommentsControl()
        {
            InitializeComponent();
        }

        public void Load(ArticleEntry e)
        {
            //-- This needs to be called first.
            // We can't call it after we load the VM and set the DataContext because
            // the comments in List Box haven't been realized yet. So basically we scroll
            // to the top of the list we've already loaded, then rebind. The list will still
            // be at the top. This was easier then getting a handle to the ListBoxes's internal 
            // ScrollViewer and scrolling it.
            ScrollToTop();

            _ViewModel = new VMComments();
            _ViewModel.Load((long)e.Id);
            DataContext = _ViewModel;
            AppBarHelper.AddCommentAction = AddComment;            
        }

        private void AddComment()
        {
            CreateAndShowInputPrompt("Add Comment", "", comment =>
            {
                _ViewModel.AddComment(comment);
            });
        }

        private void ScrollToTop()
        {
            if (lb.Items.Count > 0)
            {
                var first = lb.Items[0];
                if (first != null)
                    lb.ScrollIntoView(first);
            }
        }

        private void Comment_DoubleTap(object sender, System.Windows.Input.GestureEventArgs e)
        {
            var fe = sender as FrameworkElement;
            var vm = fe.DataContext as VMComment;

            if (vm == null) return;

            vm.IsRepliesVisible = !vm.IsRepliesVisible;
        }

        private void Reply_Click(object sender, RoutedEventArgs e)
        {
            var b = sender as Button;
            var vm = b.DataContext as VMComment;

            CreateAndShowInputPrompt("Add Reply", string.Format(@"Reply to {0}'s comment.", vm.UserName), comment =>
            {
                _ViewModel.AddComment(comment, vm.CommentId);
            });
        }

        private void CreateAndShowInputPrompt(string title, string subTitle, Action<string> onSuccess)
        {
            if (!API.IsLoggedIn)
            {
                Factory.UI.ShowMessage("You must be logged in to post. You can log in from the Application Bar below.");
                return;
            }

            var overlayColor = ThemeManager.Background;
            overlayColor.A = 200;

            InputPrompt input = new InputPrompt
            {
                Title = title,
                Message = subTitle,
                MessageTextWrapping = TextWrapping.Wrap,
                Background = new SolidColorBrush(ThemeManager.Background),
                Foreground = new SolidColorBrush(ThemeManager.Foreground),
                Overlay = new SolidColorBrush(overlayColor),
                IsCancelVisible = true,
            };
            
            input.InputScope = new InputScope { Names = { new InputScopeName() { NameValue = InputScopeNameValue.Text } } };

            input.Completed += (s, popUp) => {
                IsAddCommentDialogVisible = false;
                if (popUp.PopUpResult == PopUpResult.Ok)
                {
                    onSuccess(popUp.Result);
                }
            };

            IsAddCommentDialogVisible = true;
            input.Show();
        }
    }

    public class CommentMarginConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            try
            {
                var x = (int)value;
                var topMargin = GetParam(parameter);

                if (x < 1)
                    return new Thickness(1, topMargin, 1, topMargin);
                else
                    return new Thickness(x * 10, topMargin, 1, topMargin);
            }
            catch { return new Thickness(1); }
        }

        private static double GetParam(object param)
        {
            try
            {
                return double.Parse(param.ToString());
            }
            catch {}

            return 1;
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }

    public class CommentOpacityConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            try
            {
                var x = (double)((int)value);

                x = (10D - x) / 10D;

                if (x < 0.3)
                    return 0.3;
                else
                    return x;
            }
            catch { return 1; }
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }

    public class CommentBrushConverter : IValueConverter
    {
        public Brush ThreadReplyBrush { get; set; }
        public Brush CommentReplyBrush { get; set; }

        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            try
            {
                var nestingDepth = (int)value;
                if (nestingDepth > 0)
                    return CommentReplyBrush;
                else
                    return ThreadReplyBrush;
            }
            catch { return value; }
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
}
